Add context command support for chat turns - #1124
Conversation
Greptile SummaryThis PR adds an optional
Confidence Score: 5/5Safe to merge — the feature is additive, opt-in (defaults to None), and the command runner correctly handles all known failure modes (timeout, truncation, non-zero exit, pipe deadlock). The implementation addresses the output-size cap, working-directory propagation, and warn-vs-debug log level that were flagged in prior rounds. No new correctness issues were found across the runner, chat service, gateway, or Codex transport changes. No files require special attention.
|
| Filename | Overview |
|---|---|
| crates/common/src/context_command.rs | New module implementing the core context command runner with 30s timeout, 32KB stdout cap, concurrent stderr draining to prevent pipe deadlocks, and proper kill-on-drop cleanup. Well-structured with tests covering empty input, success, failure, working-dir, and truncation cases. |
| crates/chat/src/service/types.rs | Refactors resolve_project_context to return (Option, Option), adds resolve_turn_context that merges project file context and command output, and adds merge_context_sections. Well-tested; sequential awaiting is required since working_dir is a dependency for run_context_command. |
| crates/gateway/src/external_agents.rs | Adds resolve_context_working_dir (worktree-aware), wires context_command output into ContextSnapshot.project_context for external-agent turns, and renames context_from_history to context_from_history_with_project_context. Project-file context was already absent from external-agent snapshots pre-PR. |
| crates/external-agents/src/runtimes/codex.rs | Forwards context to Codex app-server via build_process_input, adds an outer per-turn timeout complementing the existing per-line timeout in consume_turn, and adds params/delta extraction to extract_message. All changes are additive and safe. |
| crates/config/src/schema/chat.rs | Adds optional context_command: Option field with serde default None. Schema map and validation updated accordingly. |
| docs/src/configuration-reference.md | Documents the new context_command field with accurate timeout and cap values, and correct working-directory behavior. |
Sequence Diagram
sequenceDiagram
participant User
participant ChatService
participant DB as ProjectService/DB
participant Cmd as context_command
participant LLM
User->>ChatService: chat turn (send)
ChatService->>DB: resolve_project_context(session, conn)
DB-->>ChatService: (project_context_str, working_dir)
ChatService->>Cmd: run_context_command(cmd, working_dir)
Note over Cmd: 30s timeout, 32KB cap
Cmd-->>ChatService: command_context (or None)
ChatService->>ChatService: merge_context_sections()
ChatService->>LLM: send prompt + merged context
LLM-->>ChatService: response stream
ChatService-->>User: streamed response
Note over ChatService: External-agent path
User->>ChatService: external agent turn
ChatService->>DB: resolve_context_working_dir(session)
DB-->>ChatService: working_dir (or None)
ChatService->>Cmd: run_context_command(cmd, working_dir)
Cmd-->>ChatService: context_command_output
ChatService->>ChatService: context_from_history_with_project_context()
ChatService->>LLM: "send_prompt(text, ContextSnapshot{project_context})"
LLM-->>ChatService: ExternalAgentEvents
ChatService-->>User: streamed response
Reviews (3): Last reviewed commit: "fix(context-command): cap output size an..." | Re-trigger Greptile
- Downgrade empty-output log from warn! to debug! — operators may conditionally emit context, so silence is not an error. - Resolve project context and context command concurrently via tokio::join! instead of sequentially, avoiding double latency on every chat turn. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
@greptileai review |
…xt-command # Conflicts: # crates/config/src/template.rs
Addresses Greptile review feedback on the context command feature. - Cap stdout at 32,000 bytes (mirrors workspace_file_max_chars) so a misconfigured command (e.g. `cat /var/log/app.log`) cannot exhaust server memory or blow past the model context window. Reads are bounded via a take-limited reader; the process is killed once the cap is hit. stderr is drained concurrently in a bounded task to avoid a pipe-buffer deadlock, and kill_on_drop reaps the child on timeout. - Thread the effective working directory (session worktree, else bound project directory) into run_context_command at both call sites so operator scripts run where they expect instead of the server cwd. - Fix a merge artifact where external_full_context still referenced the renamed context_from_history helper. - Document the working-directory, timeout, and size-cap behavior in the config template and configuration reference.
|
@greptile review |
Summary
Adds an optional
chat.context_commandthat runs before each chat turn and appends stdout to the prompt context. This lets deployments inject generated runtime context without manually pasting it into each session.The implementation covers:
Validation
cargo fmt --all -- --checkcargo test -p moltis-common context_command -- --nocapturecargo test -p moltis-config context_command -- --nocapturecargo test -p moltis-chat merge_context_sections -- --nocapturecargo test -p moltis-gateway context_from_history_includes_project_context -- --nocapturecargo test -p moltis-external-agents runtimes::codex::tests -- --nocapture